#!/usr/bin/env python3
"""
修复refresh端点的数据库依赖问题
"""
import sys
import os
import traceback
import logging

# 添加当前目录到Python路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

# 设置日志
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("fix_refresh")

# FastAPI相关
from fastapi import FastAPI, HTTPException, Depends, Request
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session

# 应用模块
from models import User, RefreshToken
from auth import AuthHandler, create_refresh_token_record, revoke_refresh_token, cleanup_expired_tokens
from database import get_db, engine, SessionLocal
from schemas import RefreshTokenRequest, Token

# 创建修复版的数据库依赖
def get_db_fixed():
    """
    修复版的数据库依赖 - 不自动回滚
    """
    db = SessionLocal()
    try:
        yield db
        # 移除自动commit和rollback，让函数内部自己处理
    except Exception as e:
        logger.error(f"数据库依赖异常: {e}")
        # 重新抛出异常，让上层处理
        raise
    finally:
        db.close()

# 创建修复版的refresh端点
def create_refresh_router():
    """创建修复版的refresh路由"""
    from fastapi import APIRouter, status
    from datetime import datetime, timedelta
    
    router = APIRouter()
    
    @router.post("/refresh", response_model=Token)
    async def refresh_token_fixed(
        refresh_data: RefreshTokenRequest,
        db: Session = Depends(get_db_fixed)  # 使用修复版的依赖
    ):
        """修复版的刷新访问令牌"""
        try:
            logger.info("🚀 开始执行refresh逻辑")
            
            # 验证刷新令牌
            logger.info("1️⃣ 验证刷新令牌")
            payload = AuthHandler.verify_token(refresh_data.refresh_token)
            username = payload.get("sub")
            token_type = payload.get("type")
            
            if username is None or token_type != "refresh":
                logger.error(f"无效的refresh token: username={username}, type={token_type}")
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="无效的刷新令牌"
                )
            
            logger.info("2️⃣ 检查令牌是否被撤销")
            refresh_token_record = db.query(RefreshToken).filter(
                RefreshToken.token == refresh_data.refresh_token,
                RefreshToken.is_revoked == False
            ).first()
            
            if not refresh_token_record:
                logger.error("令牌已失效")
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="令牌已失效"
                )
            
            logger.info("3️⃣ 获取用户")
            user = db.query(User).filter(User.username == username).first()
            if not user:
                logger.error(f"用户不存在: {username}")
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="用户不存在"
                )
            
            logger.info("4️⃣ 创建新的访问令牌")
            access_token_expires = timedelta(minutes=60)
            access_token = AuthHandler.create_access_token(
                data={"sub": user.username}, expires_delta=access_token_expires
            )
            
            logger.info("5️⃣ 创建新的刷新令牌")
            refresh_token_expires = timedelta(days=7)
            new_refresh_token = AuthHandler.create_refresh_token(
                data={"sub": user.username}, expires_delta=refresh_token_expires
            )
            
            logger.info("6️⃣ 撤销旧令牌，保存新令牌")
            # 使用修复的数据库操作
            try:
                revoke_refresh_token(db, refresh_data.refresh_token)
                create_refresh_token_record(
                    db, user.id, new_refresh_token,
                    datetime.utcnow() + refresh_token_expires
                )
                db.commit()  # 手动提交
                logger.info("✅ 数据库操作成功")
            except Exception as e:
                logger.error(f"数据库操作失败: {e}")
                logger.error("异常追踪:")
                traceback.print_exc()
                db.rollback()
                raise HTTPException(
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                    detail=f"数据库操作失败: {str(e)}"
                )
            
            logger.info("🎉 Refresh逻辑执行成功")
            return Token(
                access_token=access_token,
                expires_in=3600,
                refresh_token=new_refresh_token
            )
            
        except HTTPException:
            logger.error("HTTP异常，重新抛出")
            raise
        except Exception as e:
            logger.error(f"💥 Refresh端点异常: {e}")
            logger.error("异常追踪:")
            traceback.print_exc()
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"服务器内部错误: {str(e)}"
            )
    
    return router

# 创建FastAPI应用
app = FastAPI(title="Fixed Refresh API")
app.include_router(create_refresh_router(), prefix="/api/auth", tags=["auth"])

# 创建测试客户端
client = TestClient(app)

def test_fixed_refresh():
    """测试修复版的refresh端点"""
    logger.info("=== 测试修复版的refresh端点 ===")
    
    try:
        # 获取数据库会话和最新token
        db = SessionLocal()
        
        latest_token = db.query(RefreshToken).filter(
            RefreshToken.is_revoked == False
        ).order_by(RefreshToken.created_at.desc()).first()
        
        if not latest_token:
            logger.error("❌ 没有找到有效的refresh token")
            return False
            
        logger.info(f"✓ 获取到token: {latest_token.token[:50]}...")
        
        # 关闭数据库会话
        db.close()
        
        # 准备请求数据
        refresh_data = {
            "refresh_token": latest_token.token
        }
        
        logger.info(f"📡 发送POST请求到 /api/auth/refresh")
        
        # 发送请求
        response = client.post("/api/auth/refresh", json=refresh_data)
        
        logger.info(f"📊 响应状态码: {response.status_code}")
        logger.info(f"💬 响应内容: {response.text}")
        
        if response.status_code == 200:
            logger.info("✅ Refresh成功!")
            try:
                response_data = response.json()
                logger.info(f"🎉 新access_token: {response_data.get('access_token', '')[:50]}...")
                logger.info(f"🎉 新refresh_token: {response_data.get('refresh_token', '')[:50]}...")
            except Exception as e:
                logger.error(f"解析响应失败: {e}")
            return True
        else:
            logger.error("❌ Refresh失败!")
            try:
                error_data = response.json()
                logger.error(f"🚨 错误详情: {error_data}")
            except Exception as e:
                logger.error(f"解析错误响应失败: {e}")
            return False
        
    except Exception as e:
        logger.error(f"💥 测试过程中发生异常: {e}")
        logger.error("异常追踪:")
        traceback.print_exc()
        return False

if __name__ == "__main__":
    logger.info("开始测试修复版的refresh端点...")
    
    success = test_fixed_refresh()
    
    logger.info(f"\n📊 测试结果: {'✅ 成功' if success else '❌ 失败'}")
    
    if success:
        logger.info("\n🎉 修复方案有效!")
        logger.info("问题解决方案:")
        logger.info("1. 修复get_db()依赖，不自动回滚")
        logger.info("2. 在refresh端点中手动处理数据库提交")
        logger.info("3. 添加详细的异常处理和日志")
    else:
        logger.info("\n❌ 修复方案无效，需要进一步调查")